package br.com.iswe.gerador.velocity.info;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;

@SuppressWarnings("unchecked")
public class InfoGerador {

	
    private static final String ALL = "all";
	private static final String GERADOR_CONFIG_XML = "gerador.config.xml";
    private static final String GERADOR_PASTA_BASE_SAIDA = "gerador.pasta.base.saida";
    private static final String ABSTRATOS = "abstratos";
    private static final String GERADOR_ABSTRACT_PAKAGE = "gerador.abstract.pakage";
    
	private Properties propriedades = new Properties();

	private ArquivosConfig arquivosConfig = null;
	
	//E utilizado quando um cliente (q esta rodando o gerador precisa expor o seu class loader)
	private ClassLoader runnerClassLoader = Thread.currentThread().getContextClassLoader();
	
    private static final ThreadLocal<InfoGerador> infoGeradorContext = new ThreadLocal();
    
    public static InfoGerador getInfoGeradorInContext(){
        return infoGeradorContext.get();
    }
    
    public static InfoGerador getInstance(String geradorProperties) {
        return new InfoGerador(geradorProperties);
    }
    
	private InfoGerador(String configFile){
		try{
			propriedades.load(runnerClassLoader.getResourceAsStream(configFile));
            //verifica se deve carregar algum xml de configuracao complementar para o gerador.
            String configXml = propriedades.getProperty(GERADOR_CONFIG_XML);
            if( configXml != null && !"".equals(configXml)){
            	arquivosConfig = new ArquivosConfig(configXml, runnerClassLoader);
            }
		}
		catch(IOException exp){
			exp.printStackTrace();
            throw new RuntimeException("Erro ao tentar carregar arquivo de properties: " + configFile, exp);
		}
        infoGeradorContext.set(this);
	}

    public InfoGerador(Hashtable properties){
		try{
			propriedades.putAll(properties);
		}
		catch(Exception exp){
			exp.printStackTrace(); 
		}
	}
	private List<String> listaGeradores = new ArrayList<String>();
	
	public void removerGeradores(){
		listaGeradores.clear();
	}
	
	public void addGerador(String nomeGerador){
		listaGeradores.add(nomeGerador);
	}
	public List<String> getListaGeradores() {
		return listaGeradores;
	}
	public String getPropriedade(String prop) {
		return propriedades.getProperty(prop);
	}
	public String getPastaBaseSaida() {
		return propriedades.getProperty(GERADOR_PASTA_BASE_SAIDA);
	}
	
	/**
	 * M�todo utilit�rio que converte uma package java ex : 
	 * br.com.jtur.entidades em um caminho de diretorios
	 * br\com\jtur\entidades
	 * @param packageBO
	 * @return
	 */
	public String getPathFromPackage(String packg) {
		return packg.replace('.', File.separatorChar);
	}

	public ClassLoader getRunnerClassLoader() {
		return runnerClassLoader;
	}

	public void setRunnerClassLoader(ClassLoader runnerClassLoader) {
		this.runnerClassLoader = runnerClassLoader;
	}
    
    
    public String getPacoteAbstratos() {
        String pacoteAbstratos = getPropriedade(GERADOR_ABSTRACT_PAKAGE);
        if(pacoteAbstratos == null || "".equals(pacoteAbstratos)){
            pacoteAbstratos = ABSTRATOS;
        }
        return pacoteAbstratos;
    }

    /**
     * Metodo que verifica se o arquivo deve ser criado, levando em consideracao:
     *  - O tipo de artefato Ex. para uma classe de implementacao so deve gerar caso ainda nao exista
     *  - Filtros estabelecidos: Caso tenha sido especificado na lista de arquivos que esse arquivo deve ser ignorado
     *                           no momento da geracao.
     * @param arquivo
     * @return
     */
    public boolean shouldGenerateFile(String arquivo, String categoryName) {
        return arquivosConfig.shouldGenerateFile(arquivo, categoryName);
    }
    public boolean shouldGenerateFile(String arquivo) {
        return shouldGenerateFile(arquivo, ALL);
    }
	
}
